home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Copyright 1993, 1994, Cornell University
-
- Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose
- and without fee, provided that these copyright and permission notices appear on all copies and
- supporting documentation, the name of Cornell not be used in advertising or publicity pertaining
- to distribution of the program without specific prior permission, notice be given in supporting
- documentation that copying and distribution is by permission of Cornell. CORNELL MAKES NO
- REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED. By way of example, but not limitation,
- CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
- PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
- TRADEMARKS, OR OTHER RIGHTS. Cornell shall not be held liable for any liability with respect to
- any claim by the user or any other party arising from use of the program.
-
- This material is partially based on work sponsored by the National Science Foundation under Cooperative
- Agreement No. NCR-9318337. The government has certain rights in this material.
-
- */
-
- #define __MAIN__
-
- #include <stdio.h>
- #include <signal.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
-
- #ifndef LINUX
- #include <sys/socketvar.h>
- #endif
-
- #include <sys/time.h>
- #include <netinet/in.h>
-
- #include "reflect.h"
- #include "refmon.h"
- #include "globals.h"
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- unsigned char *msg,*s,*cptr,*cptr1,version;
- VideoPacketHeader *vidptr, *vtmp;
- RefConPkt pkt;
- RefConPkt *conpkt;
- client *cltptr,*ctmp;
- vat_client *mcltptr,*mtmp;
- struct sockaddr_in csock,clnt_addr;
- struct in_addr in;
- int msglen,type;
- short datatype;
- struct timeval tp;
- struct timezone tzp;
- char *tmp;
-
-
- argc--; argv++;
-
- tracefile = LOGFILE;
- maxallowed = DEFMAXCLIENT;
-
- cap = ((1024 * 80) /8);
- cap += (cap * .2);
-
- if (argc > 0)
- load_config(*argv);
- else
- load_config(NULL);
-
- if (strlen(ci_buf) == 0)
- strcpy(ci_buf,CFD);
-
- if (strlen(mp_buf) == 0)
- strcpy(mp_buf,MAX_CL);
-
- if (strlen(dy_buf) == 0)
- strcpy(dy_buf,DENY_ACCESS);
-
- if (strlen(cap_buf) == 0)
- strcpy(cap_buf,CAPMSG);
-
- if (strlen(ml_buf) == 0)
- strcpy(ml_buf,MLMSG);
-
- if (strlen(ms_buf) == 0)
- strcpy(ms_buf,MSMSG);
-
- if (maxsenders == -1)
- maxsenders = maxallowed;
-
- if (maxlurkers == -1)
- maxlurkers = maxallowed;
-
- if (log_limit != 0)
- {
- if (strcmp(tracefile,"stdout") == 0)
- log_file = stdout;
- else
- {
- if ((log_file = fopen(tracefile,"w")) != NULL)
- {
- #ifdef _BSD
- setlinebuf(log_file);
- #else
- setvbuf(log_file,NULL,_IOLBF,0);
- #endif
- dolog("open_log file: %s\n",tracefile);
- }
- else
- log_limit = 0;
- }
- }
-
- signal(SIGTERM, proc_sig);
- signal(SIGINT, proc_sig);
-
- get_my_addr(&myaddr);
- if (myaddr.sin_addr.s_addr == 0)
- {
- dolog("Unable to get a internet address\n");
- exit(1);
- }
-
- init_mem();
- init_socket();
- init_timer();
- open_bcc_servers();
-
- gettimeofday(&tp, &tzp);
- tmp = ctime(&tp.tv_sec);
- tmp[24] = ' ';
- bcopy(tmp,start_time,strlen(tmp));
-
- msg = &buffer[40];
- vidptr = (VideoPacketHeader *) msg;
- while (1)
- {
- type = receive(msg,&msglen,&csock);
- pkts_in++;
- bytes_in += msglen;
-
- if (deny(csock))
- {
- clnt_addr.sin_family = AF_INET;
- clnt_addr.sin_port = htons(VID_PORT);
- bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
- write_msg(&clnt_addr,kMessageType1,dy_buf);
- continue;
- }
-
- switch (type)
- {
- /* process VAT, MAVEN, and NV packets */
-
- case VAT_CNTL:
- case MAVEN_CNTL:
- case VAT:
- case MAVEN:
- case NV_UCAST:
- case NV_MCAST:
-
- mbone_pkt(msg,msglen,csock,type);
- break;
-
- case REF1VIDEO:
- case REF2VIDEO:
- case VIDEO:
-
- #ifdef DEBUG
- if (debug)
- {
- if (ntohs(vidptr->message) == kAudio)
- printf("AUDIO\n");
- printf("video packet len %d network src %s ", msglen, inet_ntoa(csock.sin_addr));
- in.s_addr = vidptr->routing.src.addr;
- printf("content src %s ",inet_ntoa(in));
- printf("family %d seq %ld msg %d dtype %d\n", ntohs(vidptr->routing.dest.family),
- ntohl(vidptr->seqNum), ntohs(vidptr->message),ntohs(vidptr->dataType));
- }
- #endif
- /* JAL 5/11 move this check to the very beginning */
-
- if (vidptr->routing.src.addr == 0)
- {
- dolog("received a packet with a 0 source address from %s\n",inet_ntoa(csock.sin_addr));
- break;
- }
-
- if ((cltptr = find_client(csock.sin_addr.s_addr)) == NULL)
- {
- #ifdef DEBUG
- if (debug)
- printf("client not found \n");
- #endif
- if (type == VIDEO)
- {
- if ((type = get_type(vidptr,csock)) == -1)
- {
- dolog("client not found and packet being dropped due to address or configuration restrictions\n");
- break;
- }
- }
- else
- if (type == REF1VIDEO)
- type = REF1_SERVER;
- else
- type = REF2_SERVER;
-
-
- if (ntohs(vidptr->dataType) == kConfigRefType)
- {
- if ((type != BCC_SERVER) && (type != BCC_CLIENT) && (type != REF3_SERVER) && (type != BCC_GCLIENT))
- {
- dolog("Reflector configuration mis-match from %s\n",inet_ntoa(csock.sin_addr));
- break;
- }
- }
- else
- if ((ntohs(vidptr->dataType) != kConfigVideoType) || (ntohs(vidptr->message) != kOpenConnection))
- {
- dolog("client not found and initial message is not Open\n");
- break;
- }
-
-
- if ((type == CLIENT) && (conference_id != 0))
- if ((ntohs(vidptr->conferenceid) != conference_id) && ((conference_id & 0x8000) == 0))
- {
- dolog("conference ids do not match %d %d\n",ntohs(vidptr->conferenceid),conference_id);
- clnt_addr.sin_family = AF_INET;
- clnt_addr.sin_port = htons(VID_PORT);
- bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
- write_msg(&clnt_addr,kMessageType1,ci_buf);
- break;
- }
-
- cptr = (unsigned char *) ((unsigned char *) vidptr + HEADERLEN) +
- sizeof(cltptr->clnt_config.clientCount) +
- sizeof(cltptr->clnt_config.seqNum) +
- sizeof(cltptr->clnt_config.name) +
- sizeof(cltptr->clnt_config.sendMode) +
- sizeof(cltptr->clnt_config.recvMode) +
- sizeof(cltptr->clnt_config.flags);
-
- version = *cptr;
-
- cptr1 = (unsigned char *) ((unsigned char *) vidptr + HEADERLEN) +
- sizeof(cltptr->clnt_config.clientCount) +
- sizeof(cltptr->clnt_config.seqNum) +
- sizeof(cltptr->clnt_config.name) +
- sizeof(cltptr->clnt_config.sendMode) +
- sizeof(cltptr->clnt_config.recvMode);
-
- /* assume version == 1 is a PC client */
-
- if (((*cptr1 & PC_CLIENT) || (version == 1)) && (min_pc_version != 0))
- {
- if (version < min_pc_version)
- {
- dolog("old PC version # %d is being rejected\n",version);
- clnt_addr.sin_family = AF_INET;
- clnt_addr.sin_port = htons(VID_PORT);
- bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
- write_msg(&clnt_addr,kMessageType1,mv_pc_buf);
- break;
- }
- }
- else
- if (min_mac_version != 0)
- {
- if (version < min_mac_version)
- {
- dolog("old MAC version # %d is being rejected\n",version);
- clnt_addr.sin_family = AF_INET;
- clnt_addr.sin_port = htons(VID_PORT);
- bcopy(&vidptr->routing.src.addr,&clnt_addr.sin_addr,4);
- write_msg(&clnt_addr,kMessageType1,mv_mac_buf);
- break;
- }
- }
-
- if ((cltptr = open_connection(vidptr,&csock,type)) != NULL)
- distribute(vidptr,cltptr,TRUE);
-
- break;
- }
-
- #ifdef DEBUG
- if (debug)
- {
- if (cltptr->clnt_flags & CLIENT)
- printf("CLIENT\n");
-
- if (cltptr->clnt_flags & BCC_CLIENT)
- printf("BCC_CLIENT\n");
- if (cltptr->clnt_flags & BCC_SERVER)
- printf("BCC_SERVER\n");
- if (cltptr->clnt_flags & BCC_ORIGIN)
- printf("BCC_ORIGIN\n");
-
- if (cltptr->clnt_flags & REF1_CLIENT)
- printf("REF1_CLIENT\n");
- if (cltptr->clnt_flags & REF1_SERVER)
- printf("REF1_SERVER\n");
- if (cltptr->clnt_flags & REF1_ORIGIN)
- printf("REF1_ORIGIN\n");
-
- if (cltptr->clnt_flags & REF2_SERVER)
- printf("REF2_SERVER\n");
- if (cltptr->clnt_flags & REF2_ORIGIN)
- printf("REF2_ORIGIN\n");
-
- if (cltptr->clnt_flags & REF3_SERVER)
- printf("REF3_SERVER\n");
- if (cltptr->clnt_flags & REF3_ORIGIN)
- printf("REF3_ORIGIN\n");
- if (cltptr->clnt_flags & BCC_GCLIENT)
- printf("BCC_GCLIENT\n");
- }
- #endif
-
- #ifdef DEBUG
- if (debug)
- printf("client found \n");
- #endif
- cltptr->clnt_rtimer = 0;
-
- /* if this is just a keep alive from a REF3 SERVER just return now */
- if ((cltptr->clnt_flags & REF3_SERVER) && ((csock.sin_addr.s_addr == vidptr->routing.src.addr)))
- break;
-
- /* if this is just a keep alive from a BCC SERVER just return now */
- if ((cltptr->clnt_flags & BCC_SERVER) && ((csock.sin_addr.s_addr == vidptr->routing.src.addr)))
- break;
-
-
- switch (ntohs(vidptr->routing.dest.family))
- {
- case kReflector:
-
- if ((ntohs(vidptr->dataType) == kConfigVideoType) &&
- (ntohs(vidptr->message) == kOpenConnection))
- {
- /* added by MAG 6/27/94 */
- if ((csock.sin_addr.s_addr) == god_ip)
- {
- if (debug)
- printf("This is the God-ip. Changing conf-id if necessary.\n");
-
- if (conference_id != ntohs(vidptr->conferenceid))
- {
- dolog("Conf-id was %d\n", conference_id);
-
- conference_id = ntohs(vidptr->conferenceid);
- cltptr->clnt_conf_id = conference_id;
-
- dolog("Conf-id changed to %d\n", conference_id);
-
- /* weed out all the clients who now have bad conf-id's */
- /* however if the god-ip changed it to 0, don't kick anybody off*/
-
- if ((conference_id != 0) && ((conference_id & 0x8000) == 0))
- remove_some_clients(conference_id);
- }
- }
-
- continue_connection(cltptr,vidptr);
- distribute(vidptr,cltptr,TRUE);
- }
- else
- if ((ntohs(vidptr->dataType) == kConfigVideoType) &&
- (ntohs(vidptr->message) == kCloseConnection))
- {
- if (cltptr->clnt_flags & (BCC_SERVER | REF1_SERVER | REF2_SERVER | REF3_SERVER))
- {
- if ((cltptr = find_client(vidptr->routing.src.addr)) == NULL)
- {
- in.s_addr = vidptr->routing.src.addr;
- dolog("Unable to find server's client at %s for close\n",inet_ntoa(in));
- break;
- }
- }
-
- dolog("closing connection from %s\n",cltptr->clnt_config.name);
-
- if ((cltptr->clnt_flags & HOLD_DOWN) == 0)
- hold_down_client(cltptr);
-
- distribute(vidptr,cltptr,TRUE);
-
- cltptr->clnt_flags |= HOLD_DOWN;
-
- }
- break;
-
- case kClient:
- if ((ctmp = find_client(vidptr->routing.dest.addr)) == NULL)
- {
- in.s_addr = vidptr->routing.dest.addr;
- dolog("Unable to find the destination client at %s for a kClient mesg\n",inet_ntoa(in));
- dolog("msg from %s\n",inet_ntoa(csock.sin_addr));
- break;
- }
-
- if (ntohs(vidptr->message) == kAudio)
- {
- if (cltptr->clnt_talker == 0)
- dolog("%s is speaking privetly to %s\n",cltptr->clnt_config.name,ctmp->clnt_config.name);
-
- if (cltptr->clnt_talker++ > 50)
- cltptr->clnt_talker = 0;
- }
-
- write_pkt(vidptr,ctmp);
- break;
-
- case kGroup:
- if (cltptr->clnt_flags & (BCC_SERVER | REF1_SERVER | REF2_SERVER | REF3_SERVER))
- {
- if ((cltptr = find_client(vidptr->routing.src.addr)) == NULL)
- {
- in.s_addr = vidptr->routing.src.addr;
- dolog("Unable to find server's client at %s for group\n",inet_ntoa(in));
- break;
- }
- }
-
- datatype = ntohs(vidptr->dataType);
-
- if (datatype == kAudio)
- distribute_audio(vidptr,cltptr);
- else
- if ((datatype <= kMaxVideoDataType) && (datatype >= kMinVideoDataType))
- {
- cltptr->clnt_bytecnt += msglen;
- distribute(vidptr,cltptr,FALSE);
- }
- else
- if (datatype == kAuxDataTypeData)
- distribute_aux(vidptr,cltptr);
- else
- if (datatype == kAuxDataTypeSupervisor)
- distribute(vidptr,cltptr,TRUE);
-
- break;
-
- default:
- dolog("unknown video message type\n");
- break;
- }
- break;
-
-
- case CONTROL:
- #ifdef DEBUG
- if (debug)
- printf("process control packet\n");
- #endif
- conpkt = (RefConPkt *) msg;
-
- if (msglen < MINREFPKT)
- {
- dolog("msglen is less then MINREFPKT\n");
- break;
- }
-
- if (msglen < ntohs(conpkt->msg_len))
- {
- dolog("conpkt->msg_len is less then msglen\n");
- break;
- }
-
- process_control_pkt(conpkt);
-
- break;
-
- default:
- dolog("bad value returned from receive\n");
- exit(1);
- }
-
- if (timer_expired)
- {
- timer_expired--;
- do_timer();
- }
- }
- }
-
- init_mem()
- {
- unsigned char *stash;
- client *cltptr;
- slist *sptr;
- int cnt;
-
-
-
- if ((stash = (unsigned char *) calloc(MAXCLIENT,sizeof(client))) == NULL)
- {
- dolog("Unable to get client memory\n");
- exit(1);
- }
-
- for (cnt = 0, cltptr = (client *) stash; cnt < MAXCLIENT; cnt++, cltptr++)
- free_client(cltptr);
-
- if ((stash = (unsigned char *) calloc((MAXCLIENT * MAXCLIENT * 3),sizeof(slist))) == NULL)
- {
- dolog("Unable to get slist memory \n");
- exit(1);
- }
-
- for (cnt = 0, sptr = (slist *) stash; cnt < (MAXCLIENT * MAXCLIENT * 3); cnt++, sptr++)
- free_slist(sptr);
- }
-
-